package data.result;

import data.component.Line;
import utils.Matrix;
import data.cad.CAD;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Set;
import java.util.stream.Collectors;

import static java.util.Arrays.asList;

public class MeasureValue {

    /**值*/
    public ArrayList<String> value;

    /**标准判断，0未判断，1合格，2不合格，3爆点*/
    public String result;

    /**对应尺序*/
    public String ruleNo;

    /**设计值*/
    public String designValues;

    /**坐标(x,y,z)*/
    public ArrayList<ArrayList<Double>> coordinate;

    /**经过模糊匹配转换后的坐标，转换此坐标可得到PDF坐标*/
    public ArrayList<Double> cadCoordinate;

    /**等高线下尺位置*/
    public ArrayList<ArrayList<Double>> rulers;

    /**等高线2D坐标*/
    public ArrayList<Double> contourCoordinate;

    /**测量值Id*/
    public String id;

    /**匹配分数（内部使用）*/
    public Double matchScore;

    /**任务id（合并后用以区别）*/
    public String taskid;

    /**站点id（合并后用以区别）*/
    public String pointid;

    /**子墙ID（内部使用）*/
    public String subWallId;

    /**墙类型*/
    public String wallType;

    /**等高线不良下尺信息*/
    public ExtraValue extraValue;

    /**墙面特征（开关，变电箱等）*/
    public String feature;

    /**等高线不良类型*/
    public String critical_type;

    /**图纸下尺坐标*/
    public ArrayList<ArrayList<Double>> cadRulers;

    /**3D模型下尺坐标*/
    public ArrayList<ArrayList<Double>> modelRulers;


    public void SetMeasureValue(String itemId, Matrix m, Double score, Double angle)
    {
        var longWidthItem =new ArrayList<> (asList("8","9", "913", "914", "915", "916"));
        if (longWidthItem.contains(itemId))
        {
            SetCadRulers(m);
        }

        SetCadCoordinate(m, angle);

        SetMatchScore(score);
    }

    public void SetMeasureValue(CAD cad, String itemId, Matrix m,  Double angle)
    {
        SetCadCoordinate(m, angle);

        var cornerItem = Set.of("4","6", "74", "73");

        if(cornerItem.contains(itemId))
        {
            SetMatchScore(cad);
        }

    }

    private void SetMatchScore(Double score)
    {
        this.matchScore = score;
    }

    private void SetMatchScore(CAD cad)
    {
        var roomCorners = new ArrayList<Double[]>(Arrays.asList(cad.boundingBox.min, cad.boundingBox.max, cad.boundingBox.leftUp, cad.boundingBox.rightDw, cad.boundingBox.center));
        var distanceList = roomCorners.stream().map(p-> Line.GetLength(p, this.cadCoordinate)).collect(Collectors.toList());
        var minDistance = Collections.min(distanceList);
        this.matchScore = 1 - (minDistance/Line.GetLength(cad.boundingBox.min, cad.boundingBox.max));

    }

    private void SetCadCoordinate(Matrix m, Double angle)
    {
        if (this.coordinate == null)
        {
            this.cadCoordinate = null;
            return;
        }
        var mRotate = Matrix.CreateRotationZ(angle);
        var coordinate = mRotate.Transform(this.coordinate.get(0));
        this.cadCoordinate = m.Transform(coordinate);
    }

    private void SetCadRulers(Matrix m)
    {
        this.cadRulers = new ArrayList<>();

        for (ArrayList<Double> modelRuler : modelRulers) {
            this.cadRulers.add(m.Transform(modelRuler));
        }
    }
}
